    #include "http.hpp"
    #define WWWROOT "./wwwroot/"

    //按照Http请求格式组织请求
    std::string RequestStr(const HttpRequest& req)
    {
        std::stringstream ss;
            // HTTP请求行格式 "GET /bitejiuyeke/login?user=xiaoming&pass=123123 HTTP/1.1\r\n"
        ss << req._method << " " << req._path << " " << req._version << "\r\n";

        //printf("写入查询字符串\n");
        for(auto& it : req._params)
            ss << it.first << ": " << it.second << "\r\n";

        //printf("写入头部字段\n");
        for(auto& it : req._headers)
            ss << it.first << ": " << it.second << "\r\n";

        ss << "\r\n"; //空行
        //空行之后就是正文
        ss << req._body;
        return ss.str();
    }

    void hello(const HttpRequest& req,HttpResponse* rsp)
    {
        rsp->SetContent(RequestStr(req),"text/plain"); //使用 text/plain方式解析
    }

    void login(const HttpRequest& req,HttpResponse* rsp)
    {
        rsp->SetContent(RequestStr(req),"text/plain");
    }

    void PutFile(const HttpRequest& req,HttpResponse* rsp)
    {
        std::string pathname = WWWROOT + req._path;
        Util::WriteFile(pathname, req._body); 
        //rsp->SetContent(RequestStr(req),"text/plain");
    }

    void DelFile(const HttpRequest& req,HttpResponse* rsp)
    {
        rsp->SetContent(RequestStr(req), "text/plain");
    }

    int main()
    {
        HttpServer server(8085);
        server.SetBaseDir(WWWROOT);
        server.SetThreadCount(3);

        server.AddGetRoute("/hello",hello);
        server.AddPostRoute("/login",login);
        server.AddPutRoute("/1234.txt",PutFile);
        server.AddDeleteRoute("/1234.txt",DelFile);

        server.Listen();
        return 0;
    }















    // #include "http.hpp"

    // static size_t Split(const std::string& src,const std::string& sep,std::vector<std::string>* array)
    // {
    //     size_t offset = 0; // 切割的位置
    //     //abc,def,,,ghi,
    //     while(offset < src.size())
    //     {
    //         size_t pos = src.find(sep,offset); //从offset位置开始找sep分割字符/串
    //         if(pos == std::string::npos) //找不到分割字符串，但是得先把最后一个位置的字符串放入array
    //         {
    //             if(pos == src.size())   
    //                 break;
    //             array->push_back(src.substr(offset));
    //             return array->size();
    //         }
    //         //找到了，分割字符串添加进array，然后offset往后走
    //         if(offset == pos) //如果找到的是一个空字符串,直接跳过不用添加进array
    //         {
    //             offset = pos + sep.size();
    //             continue;
    //         }
    //         array->push_back(src.substr(offset,pos - offset));
    //         offset = pos + sep.size();
    //     }
    //     return array->size();
    // }

    // static bool ReadFile(const std::string &filename, std::string *buf) 
    // {
    //     std::ifstream ifs(filename, std::ios::binary);
    //     if (ifs.is_open() == false) {
    //         printf("OPEN %s FILE FAILED!!", filename.c_str());
    //         return false;
    //     }
    //     size_t fsize = 0;
    //     ifs.seekg(0, ifs.end);//跳转读写位置到末尾
    //     fsize = ifs.tellg();  //获取当前读写位置相对于起始位置的偏移量，从末尾偏移刚好就是文件大小
    //     ifs.seekg(0, ifs.beg);//跳转到起始位置

    //     buf->resize(fsize); //开辟文件大小的空间
        
    //     ifs.read(&(*buf)[0], fsize);
    //     if (ifs.good() == false) 
    //     {
    //         printf("READ %s FILE FAILED!!", filename.c_str());
    //         ifs.close();
    //         return false;
    //     }
        
    //     ifs.close();
    //     return true;
    // }

    // static bool WriteFile(const std::string& filename,const std::string& data)
    // {
    //     //binary：以二进制模式打开文件trunc：将文件原有内容丢弃
    //     std::ofstream ofs(filename, std::ofstream::binary | std::ofstream::trunc);
    //     if(ofs.is_open() == false)
    //     {
    //         printf("OPEN %s FILE FAILED!!", filename.c_str());
    //         return false;
    //     }

    //     ofs.write(data.c_str(),data.size());
    //     if(ofs.good() == false)
    //     {
    //         ERROR_LOG("WRITE %s FILE FAILED!", filename.c_str());
    //         ofs.close();    
    //         return false;
    //     }
    //     ofs.close();
    //     return true;
    // }

    // static std::string URLEncode(const std::string& url,bool convert_space_to_plus)
    // {
    //     std::string ret;
    //     for(auto& c : url)
    //     {
    //         if(c == '.' || c =='-' || c == '_' || c == '~' || isalnum(c))
    //             ret += c;
    //         else if(c == ' ' && convert_space_to_plus == true)
    //             ret += '+';
    //         else // 编码格式： %HH
    //             //snprintf 与 printf比较类似，都是格式化字符串，只不过一个是打印，一个是放到一块空间中
    //         {
    //             char tmp[4];
    //             //%%：一个%，%02X：转换为两位的十六进制数，并在不足两位时用前导零填充
    //             snprintf(tmp,4,"%%%02X",c);
    //             ret +=tmp;
    //         }
    //     }
    //     return ret;
    // }

    // static char HEXTOINT(char c)
    // {
    //     if(c >= '0' && c <='9')
    //         return c - '0';

    //     if(c >= 'a' && c <='z')
    //         return c - 'a' + 10;
        
    //     if(c >= 'A' && c <='Z')
    //         return c - 'A' + 10;
        
    //     return -1;
    // }

    // static std::string URLDecode(const std::string& url,bool plus_to_convert_space)
    // {
    //     std::string ret;
    //     for(int i =0;i < url.size();i++)
    //     {
    //         if(url[i] == '+' && plus_to_convert_space == true)
    //         {
    //             ret += ' ';
    //         }
    //         else if(url[i] == '%' && (i+2) < url.size())
    //         {
    //             char v1 = HEXTOINT(url[i+1]);
    //             char v2 = HEXTOINT(url[i+2]);
    //             char v = (v1 << 4) + v2;
    //             ret += v;
    //             i+=2;
    //         }
    //         else             
    //             ret += url[i];
    //     }
    //     return ret;
    // }

    // static std::string StatuDesc(int statu)
    // {
    //     auto it = _statu_msg.find(statu);
    //     if(it == _statu_msg.end()) //找不到
    //     {
    //         return "Unknow";
    //     }
    //     return it->second;
    // }

    // static std::string ExtMime(const std::string& filename)
    // {
    //     // a.b.txt  先获取文件扩展名 
    //     //find_last_of,从filename的后往前找字符'.';
    //     size_t pos = filename.find_last_of('.');
    //     if (pos == std::string::npos) 
    //     {
    //         //告知浏览器服务器返回的是一个二进制流，这种情况下，浏览器默认的处理方式是下载文件
    //         return "application/octet-stream";
    //     }
    //     //根据扩展名，获取mime
    //     std::string ext = filename.substr(pos);
    //     auto it = _mime_msg.find(ext);
    //     if (it == _mime_msg.end()) 
    //     {
    //         return "application/octet-stream";
    //     }
    //     return it->second;
    // }

    // //判断一个文件是否是目录
    // static bool IsDirectory(const std::string &filename)
    // {
    //     struct stat st;
    //     //stat()是用来描述一个linux系统文件系统中的文件属性的结构
    //     int ret = stat(filename.c_str(),&st);
    //     if(ret < 0)
    //     {
    //         return false;
    //     }
    //     return S_ISDIR(st.st_mode); 
    // }

    // static bool IsRegular(const std::string& filename)
    // {
    //     struct stat st;
    //     //stat()是用来描述一个linux系统文件系统中的文件属性的结构
    //     int ret = stat(filename.c_str(),&st);
    //     if(ret < 0)
    //     {
    //         return false;
    //     }
    //     return S_ISREG(st.st_mode);
    // }

    // static bool IsValidPath(const std::string& path)
    // {
    //     std::vector<std::string> subdir; 
    //     Split(path,"/",&subdir);
    //     int level = 0;
    //     for(auto &str : subdir)
    //     {
    //         if(str == "..") //认为走到相对根目录之外，不合理
    //         {
    //             --level;
    //             if(level < 0)   
    //                 return false;
    //         }
    //         else
    //             ++level;
    //     }
    //     return true;
    // }

    // int main()
    // {
    //     bool ret = IsValidPath("/index.html"); 
    //     //垃圾vscode，cout打印个bool类型都不行,冯你个福的
    //     printf("%d\n",ret);
    //     ret = IsValidPath("../source/main.cpp");
    //     printf("%d\n",ret);

    // }
    //     // std::string ret = StatuDesc(200);
    //     // std::cout << ret << std::endl;
    //     // ret = StatuDesc(300);
    //     // std::cout << ret << std::endl;

    //     // std::string res = ExtMime(".txt");
    //     // std::cout << res << std::endl;
    //     // res = ExtMime(".pdf");
    //     // std::cout << res << std::endl;

    //     // std::cout << IsDirectory("http") << std::endl;
        
    //     // std::cout << IsRegular("http") << std::endl;


    //     //std::string url = "http://url?C++";
    //     // std::string url = "http://url?C++  ";
        
    //     // std::string ret = URLEncode(url,true);
        
    //     // std::cout << ret << std::endl;
        
    //     // //http%3A%2F%2Furl%3FC%2B%2B++
    //     // std::string res = URLDecode(ret,true);
    //     // std::cout << res << std::endl;

    //     // std::string buff;
    //     // bool ret = ReadFile("../muduo_source/main.cpp",&buff);
    //     // if(ret == false)
    //     // {
    //     //     return false;
    //     // }
    //     // std::cout << buff.c_str() <<std::endl;

    //     // ret = WriteFile("./test_write_file.c",buff.c_str());
    //     // if(ret == false)
    //     // {
    //     //     return false;
    //     // }
    // //     return 0;
    // // }
